package Vue;

import Model.Dame;
import Model.Damier;
import Model.Joueur;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.Border;

/**
 * Classe permettant gérer la vue, ainsi que de monitorer la partie
 * @author El Meknassi Hamza (10806466) - Migeon Cyril (11007322)
 */
public class DamierVue extends javax.swing.JFrame {

    //Tableau de cases
    private JPanel tabCasesVue;

    //Damier utilisé pour la partie
    private Damier damier;

    //Différents joueurs
    private Joueur J1;
    private Joueur J2;

    //Variable permettant de savoir si le prochain clic permettra de faire appel à la fonction déplacer ou pas
    private int deplacerOk = 0;

    //Coordonnées de la case source lors d'un appel à la fonction déplacer, leur valeur est modifiée après un premier clic
    private int xSrc=-1;
    private int ySrc=-1;

    //Int permettant d'identifier le joueur actif
    private int joueurActif = 0;

    /**
     * Constructeur de la classe
     */
    public DamierVue() {
        initComponents();
        this.setTitle("Jeu de dames");
        this.setLocationRelativeTo(null);
        damier = new Damier();
        J1 = new Joueur('b',"Joueur 1");
        J2 = new Joueur('n',"Joueur 2");
        //C'est le joueur 1 qui commence la partie
        J2.setPeutJouer(false);

        //On crée un GridLayout de 10x10, il contiendra nos 100 cases
        tabCasesVue = new JPanel (new GridLayout (10,10));
        CaseVue caseTemp;
        Border blackline = BorderFactory.createLineBorder(Color.blue,1);

        //Boucle permettant d'initialiser le damier
        for (int y=0; y<10; y++)
        {
            for (int x=0; x<10;x++)
            {
                final int tmp_x = x;
                final int tmp_y = y;
                caseTemp = new CaseVue();
                caseTemp.setBorder(blackline);
                //Si la case est active, on lui attribue un listenner
                if (damier.getCase(x,y).getEtat()==1 || damier.getCase(x,y).getEtat()==0)
                {
                    caseTemp.addMouseListener(new java.awt.event.MouseAdapter() {
                        public void mouseClicked(java.awt.event.MouseEvent evt) {
                            gererClic(tmp_x,tmp_y);
                        }
                    });
                }

                //On active une case sur deux
                if ((x+y) %2 == 0)
                    caseTemp.setEstActive(false);
                else
                    caseTemp.setEstActive(true);

                //On ajoute notre case au tableau de cases
                tabCasesVue.add(caseTemp);
            }
        }

        //Bandeau du bas permettant de savoir à quel joueur est le tour
        this.nomJ1Label.setText(J1.getNom());
        this.nomJ2Label.setText(J2.getNom());
        this.nomJ1Label.setEnabled(true);
        this.nomJ2Label.setEnabled(false);
        //Images pour savoir les couleurs de chaque joueur
        CaseVue pionJ1 = new CaseVue();
        CaseVue pionJ2 = new CaseVue();
        pionJ1.setBorder(blackline);
        pionJ1.setJoueur(2);
        pionJ1.setEstActive(true);
        pionJ1.setBounds(20, 05, 35, 35);
        pionJ2.setBorder(blackline);
        pionJ2.setJoueur(1);
        pionJ2.setEstActive(true);
        pionJ2.setBounds(0, 05, 35, 35);
        pionJ2.repaint();
        this.panelJ1.add(pionJ1);
        this.panelJ2.add(pionJ2);
        this.add(tabCasesVue);

        //taille de la fenêtre et du plateau
        tabCasesVue.setSize(500, 500);
        tabCasesVue.setVisible(true);
        this.setVisible(true);
        this.setSize(506, this.getHeight());

        //Comme le joueur 1 commence, on cherche les pièces qu'il peut jouer
        this.damier.setPiecesJouables(J1);

        //Fonction permettant de colorier le damier en fonction de l'état du damier (de la classe Damier.java)
        colorierDamier();
    }

    /**
     * Fonction permettant d'identifier les différentes cases en fonction de leurs coordonnées
     * @param a
     * @param b
     * @return id - L'identifiant de la case de coordonnées (a,b)
     */
    private int correspondance(int a, int b)
    {
        int id = 0;
        int tabId[][] = new int [10][10];
        for (int y=0; y<10; y++)
        {
            for (int x=0; x< 10; x++)
            {
                tabId[x][y]=id;
                id++;
            }
        }
        return tabId[a][b];
    }

    /**
     * Fonction permettant de colorier le damier (colorier les pions etc ...)
     */
    private void colorierDamier()
    {
        int id = 0;
        for (int y=0; y<10; y++)
        {
            for (int x=0; x< 10; x++)
            {
                if (damier.getCase(x, y).getEtat()==1)
                {
                    if (damier.getCase(x,y).getPiece().getCouleur() == 'n')
                        ((CaseVue) tabCasesVue.getComponent(id)).setJoueur(1);
                    else
                        ((CaseVue) tabCasesVue.getComponent(id)).setJoueur(2);
                }
                else if (damier.getCase(x, y).getEtat()==0)
                    ((CaseVue) tabCasesVue.getComponent(id)).setJoueur(0);
                if (damier.getCase(x, y).getCaseProposee())
                    ((CaseVue) tabCasesVue.getComponent(id)).setPropose(true);
                else ((CaseVue) tabCasesVue.getComponent(id)).setPropose(false);
                ((CaseVue) tabCasesVue.getComponent(id)).repaint();
                id++;
            }
        }
    }

    /**
     * Fonction permettant d'inverser le joueur (utilisée pour les prises multiples)
     * @param numJoueur
     */
    private void reJouer(int numJoueur)
    {
        if (numJoueur == 1)
        {
            J1.setPeutJouer(true);
            J2.setPeutJouer(false);
            ((JLabel)this.panelJ1.getComponent(0)).setEnabled(true);
            ((JLabel)this.panelJ2.getComponent(0)).setEnabled(false);
        }
        else if(numJoueur == 2)
        {
            J1.setPeutJouer(false);
            J2.setPeutJouer(true);
            ((JLabel)this.panelJ1.getComponent(0)).setEnabled(false);
            ((JLabel)this.panelJ2.getComponent(0)).setEnabled(true);
        }
    }

    /**
     * Gère l'ensemble des actions (clics)
     * 
     */
    protected void gererClic(int cx, int cy)
    {
        System.out.println("Mouse clicked >> ["+cx+","+cy+"]");
        Joueur joueur = null;
        //Variable ou on stocke le résultat de la fonction déplacer
        int resDeplacement;

        //Si deplacerOk est à 1, cela veut dire qu'il s'agit d'un clic sur une case cible,
        //on essaye donc de faire un déplacement
        if (deplacerOk==1)
        {
            //On prépare l'inversion du joueur (pour gérer les tours)
            if (joueurActif == 1)
            {
                joueur = J1;
                J1.setPeutJouer(false);
                J2.setPeutJouer(true);
                ((JLabel)this.panelJ1.getComponent(0)).setEnabled(false);
                ((JLabel)this.panelJ2.getComponent(0)).setEnabled(true);
            }
            else if(joueurActif == 2)
            {
                joueur = J2;
                J1.setPeutJouer(true);
                J2.setPeutJouer(false);
                ((JLabel)this.panelJ1.getComponent(0)).setEnabled(true);
                ((JLabel)this.panelJ2.getComponent(0)).setEnabled(false);
            }

            //On fait appel à la fonction déplacer
            resDeplacement = damier.getCase(xSrc, ySrc).getPiece().deplacer(damier.getCase(xSrc, ySrc), damier.getCase(cx, cy), joueur, damier.getPiecesJouables());

            //Déplacement ou prise simple
            if (resDeplacement == 1)
            {
                //On enlève la surbrillance de la case source
                ((CaseVue) tabCasesVue.getComponent(correspondance(xSrc,ySrc))).setSelection(false);
                damier.getCase(xSrc, ySrc).setCaseProposee(false);
                //On décolorie l'ensemble des cases qui pouvaient faire une prise
                damier.viderCasesProposees();
                //On vérifie que l'on a pas une dame après le déplacement
                if (damier.getCase(cx, cy).getPiece() instanceof Dame)
                    ((CaseVue) tabCasesVue.getComponent(correspondance(cx,cy))).setDame(true);
                else ((CaseVue) tabCasesVue.getComponent(correspondance(cx,cy))).setDame(false);
                //On colorie le damier
                colorierDamier();
            }

            //Une prise multiple possible
            else if (resDeplacement == 2)
            {
                ((CaseVue) tabCasesVue.getComponent(correspondance(xSrc,ySrc))).setSelection(false);
                ((CaseVue) tabCasesVue.getComponent(correspondance(cx,cy))).setSelection(true);
                damier.viderCasesProposees();
                damier.getCase(xSrc, ySrc).setCaseProposee(false);
                damier.getCase(cx, cy).setCaseProposee(true);
                if (damier.getCase(cx, cy).getPiece() instanceof Dame)
                    ((CaseVue) tabCasesVue.getComponent(correspondance(cx,cy))).setDame(true);
                else ((CaseVue) tabCasesVue.getComponent(correspondance(cx,cy))).setDame(false);
                colorierDamier();
            }
            //Le déplacement n'a pas eu lieu (clic au mauvais endroit ou autre) -> on redonne la main au joueur
            else
            {
                ((CaseVue) tabCasesVue.getComponent(correspondance(xSrc,ySrc))).setSelection(false);
                colorierDamier();
                reJouer(joueurActif);
            }
            //Si une prise multiple est possible, on définit la case source
            //du prochain coup à la case destination du coup courant et on inverse le tour
            if (resDeplacement == 2)
            {
                reJouer(joueurActif);
                xSrc=cx;
                ySrc=cy;
            }
            //Sinon, On réinitialise les différents paramètres
            else
            {
                deplacerOk= 0;
                joueurActif = 0;
                xSrc=-1;
                ySrc=-1;
            }
        }
        //S'il s'agit du premier clic, on sauvegarde la position de la case sélectionnée
        else 
        {
            //On vérifie que la case est occupée par une pièce
            if (damier.getCase(cx, cy).getEtat()==1)
            {
                //On identifie à quel joueur appartient la pièce
                if(damier.getCase(cx, cy).getPiece().getCouleur() == 'b')
                {
                    joueurActif = 1;
                    joueur = J1;
                }
                else
                {
                    joueurActif = 2;
                    joueur = J2;
                }
                //On vérifie si le joueur peut jouer
                if (joueur.getPeutJouer())
                {
                    //On met la variable deplacerOk à 1 pour qu'au prochain clic on effectue un déplacer
                    deplacerOk = 1;
                    //On remplit le tableau des prises possibles pour ce joueur
                    damier.setPiecesJouables(joueur);
                    colorierDamier();
                    //On met un fond jaune pour la case sélectionnée
                    ((CaseVue) tabCasesVue.getComponent(correspondance(cx,cy))).setSelection(true);
                    ((CaseVue) tabCasesVue.getComponent(correspondance(cx,cy))).repaint();
                    xSrc=cx;
                    ySrc=cy;
                }
                else
                    System.out.println("Ce n'est pas votre tour !");
            }
        }
    }

    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        panelJ1 = new javax.swing.JPanel();
        nomJ1Label = new javax.swing.JLabel();
        panelJ2 = new javax.swing.JPanel();
        nomJ2Label = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        nomJ1Label.setText("Joueur 1");

        javax.swing.GroupLayout panelJ1Layout = new javax.swing.GroupLayout(panelJ1);
        panelJ1.setLayout(panelJ1Layout);
        panelJ1Layout.setHorizontalGroup(
            panelJ1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelJ1Layout.createSequentialGroup()
                .addGap(67, 67, 67)
                .addComponent(nomJ1Label)
                .addContainerGap(74, Short.MAX_VALUE))
        );
        panelJ1Layout.setVerticalGroup(
            panelJ1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelJ1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(nomJ1Label)
                .addContainerGap(27, Short.MAX_VALUE))
        );

        nomJ2Label.setText("Joueur 2");

        javax.swing.GroupLayout panelJ2Layout = new javax.swing.GroupLayout(panelJ2);
        panelJ2.setLayout(panelJ2Layout);
        panelJ2Layout.setHorizontalGroup(
            panelJ2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelJ2Layout.createSequentialGroup()
                .addGap(47, 47, 47)
                .addComponent(nomJ2Label)
                .addContainerGap(122, Short.MAX_VALUE))
        );
        panelJ2Layout.setVerticalGroup(
            panelJ2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panelJ2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(nomJ2Label)
                .addContainerGap(27, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(24, 24, 24)
                .addComponent(panelJ1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(99, 99, 99)
                .addComponent(panelJ2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(178, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(502, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(panelJ2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(panelJ1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        // TODO add your handling code here:
        int reponse = JOptionPane.showConfirmDialog(this, "Etes-vous sur de vouloir quitter l'application ?", "Quitter", JOptionPane.YES_NO_OPTION);
            if(reponse==JOptionPane.YES_OPTION)
                System.exit(0);
    }//GEN-LAST:event_formWindowClosing

   

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel nomJ1Label;
    private javax.swing.JLabel nomJ2Label;
    private javax.swing.JPanel panelJ1;
    private javax.swing.JPanel panelJ2;
    // End of variables declaration//GEN-END:variables

}
